#include "RingQueue.hpp"
#include "Thread.hpp"
#include "Task.hpp"
using namespace std;

using RingQueue_t = RingQueue<Task>;

void Consum(RingQueue_t& rq,string name)
{
    
    while (true)
    {
        sleep(2);
        // 1. 消费任务
        Task t;
        rq.Pop(&t);
        std::cout << "Consumer handler task: " << "[" << name << "]" << std::endl;
        // 2. 处理任务
        t();
    }
}

void Product(RingQueue_t& rq,string name)
{
    cout<<"  1"<<endl;
    srand(time(nullptr) ^ pthread_self());
    //int cnt = 10;
    while (true)
    {
        // 获取任务
        // 生产任务
        rq.Enqueue(Download);
        std::cout << "Productor : " << "[" << name << "]" << std::endl;
        // cnt--;
    }
}


void InitComm(vector<Thread<RingQueue_t>>* threads,int nums, RingQueue_t& rq,func_t<RingQueue_t> func,const string& who)
{
    for(int i = 0;i<nums;i++)
    {

        string name = "thread-" + to_string(i+1) + who;
        threads->emplace_back(func,rq,name);
        //threads->back().Strat();//创建线程
    }
}

void InitConsum(vector<Thread<RingQueue_t>>* threads,int nums, RingQueue_t& rq)
{
    InitComm(threads,nums,rq,Consum,"Consumer");
}

void InitProduct(vector<Thread<RingQueue_t>>* threads,int nums, RingQueue_t& rq)
{
    InitComm(threads,nums,rq,Product,"Productor");
}

void StratAllThread(vector<Thread<RingQueue_t>> threads)
{
    for(auto& thread : threads)
    {
        //std::cout << "start: " << thread.Name() << std::endl;
        thread.Start();
    }
}

void WaitAllThread(vector<Thread<RingQueue_t>> threads)
{
    for(auto thread : threads)
    {
        thread.Join();
    }
}


int main()
{
    RingQueue_t* rq = new RingQueue_t(5);//数据类型RingQueue_t
    vector<Thread<RingQueue_t>> threads;

    InitConsum(&threads,1,*rq);
    InitProduct(&threads,1,*rq);


    StratAllThread(threads);

    WaitAllThread(threads);
}